/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 martyr.h

	$Header: /heroes4/martyr.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "martyr.h"

#include "battlefield.h"
#include "battlefield_window.h"
#include "bitmap_group_cache.h"
#include "can_cast.h"
#include "combat_creature.h"
#include "combat_spell_registration.h"
#include "external_string.h"
#include "format_string.h"
#include "mouse_window.h"
#include "replace_keywords.h"
#include "spell.h"

static t_combat_spell_registration<t_spell_martyr> k_martyr_registration( k_spell_martyr );
static t_bitmap_group_cache const					k_martyr_cursor( "cursor.combat.martyr" );
static t_bitmap_group_cache const					k_martyr_client_cursor( "cursor.combat.martyr_client" );

// --------------------------------------------------------------------
// handle martyr spell
// --------------------------------------------------------------------
t_spell_martyr::t_spell_martyr( t_battlefield& battlefield, t_spell spell )
              : t_combat_spell_single_target( battlefield, spell )
{
	m_selecting_source = true;
	m_martyr_cursor.create( k_martyr_cursor.get() );
	m_martyr_client_cursor.create( k_martyr_client_cursor.get() );
}

double t_spell_martyr::ai_weight( t_combat_creature const& target ) const
{
	return 0.0;
}

double t_spell_martyr::get_cancel_weight( t_combat_creature const& target ) const
{
	return 0.0;
}

// --------------------------------------------------------------------
// handle martyr spell
// --------------------------------------------------------------------
bool t_spell_martyr::cast_on( t_combat_creature_ptr caster, 
		                      t_combat_creature_ptr target, 
							  int power,
							  bool is_mirror )
{
	t_combat_action_message message( *caster, get_action_text( is_mirror ) );

	m_battlefield.start_animation( *m_client, k_spell_effect_martyr_client, message );
	m_battlefield.start_animation( *m_spell_target, k_spell_martyr, message );
	m_client->set_spell( k_spell_martyr, message);
	m_client->set_martyr_protector( m_spell_target );
	return true;
}

// --------------------------------------------------------------------
// handle martyr spell
// --------------------------------------------------------------------
t_combat_ai_action_list t_spell_martyr::generate_combat_ai_action_list(t_combat_ai &owner)
{
	// Not implemented
	return t_combat_ai_action_list();
}

t_mouse_window* t_spell_martyr::get_spell_cursor() const
{
	if (m_selecting_source)
		return m_martyr_cursor.cursor;
	return m_martyr_client_cursor.cursor;
}

// --------------------------------------------------------------------
// handle martyr spell
// --------------------------------------------------------------------
static t_external_string const k_text_same_creature( "same_creature.spells" );
static t_external_string const k_text_protect_creatures( "protect_creatures.spells" );

t_mouse_window* t_spell_martyr::mouse_move( t_screen_point const& point,
										    std::string& help_text )
{
	if (m_selecting_source)
		return t_combat_spell_single_target::mouse_move( point, help_text );

	t_combat_creature* creature = m_battlefield.creature_hit_test( point );
	t_mouse_window*    result;

	m_battlefield.select_target( creature );
	result = m_battlefield.get_blocked_cursor();
	if (creature == 0)
		return result;

	result = m_battlefield.get_spell_cannot_cast_cursor();
	if (!::can_cast( *m_caster, m_spell, *creature, &help_text ))
		return result;
	if (creature == m_spell_target)
	{
		help_text = replace_keywords( k_text_same_creature, "%the_creatures",
			                          m_spell_target->get_name( true ) );
		return result;
	}
	help_text = replace_keywords( k_text_protect_creatures,
		                          "%the_client", creature->get_name( true ),
								  "%the_creatures", m_spell_target->get_name( true ));
	return m_martyr_client_cursor.cursor;
}

// --------------------------------------------------------------------
// handle martyr spell
// --------------------------------------------------------------------
static t_external_string const k_text_choose_client( "choose_client.spells" );
bool t_spell_martyr::left_click( t_screen_point const& point )
{
	t_combat_creature* creature = m_battlefield.creature_hit_test( point );

	if (creature == 0)
		return false;

	if (!::can_cast( *m_caster, m_spell, *creature ))
		return false;

	if (m_selecting_source)
	{
		m_spell_target = creature;
		m_battlefield.add_prompt( *creature, k_text_choose_client );
		m_selecting_source = false;
		m_battlefield.get_window()->update_cursor();
		return true;
	}
	if (creature == m_spell_target)
		return false;
	m_client = creature;
	m_battlefield.begin_spell( m_spell_target );
	return true;
}

// --------------------------------------------------------------------
// show martyr spell in action
// --------------------------------------------------------------------
t_martyr_action::t_martyr_action( t_combat_creature_ptr client, 
								  t_combat_creature_ptr creature,
		                          int damage, bool permanent )
{
	m_client = client;
	m_creature = creature;
	m_damage = damage;
	m_permanent = permanent;
}

static t_external_string const k_combat_action_martyr_protector_effect( "combat_action.martyr_protector_effect" );

// --------------------------------------------------------------------
// show martyr spell in action
// --------------------------------------------------------------------
void t_martyr_action::operator()()
{
	if (m_creature->get_number() > 0)
	{
		t_battlefield& battlefield = m_creature->get_battlefield();

		t_combat_action_message message( *m_creature, k_combat_action_martyr_protector_effect );
		battlefield.start_animation( *m_creature, k_spell_martyr, message );
		m_creature->add_damage( m_damage, 0, false, m_permanent, message);
		m_creature->check_flinch( message );
		m_creature->apply_damage( battlefield, true );
	}
}
